home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / linux-bo / etherboo.000 / etherboo / etherboot-2.0 / patches / netboot-freebsd-loads-linux-kernel.patch < prev    next >
Text File  |  1995-09-27  |  37KB  |  1,195 lines

  1. diff -u -r -N netboot-freebsd-for-linux/3c509.c netboot-freebsd/3c509.c
  2. --- netboot-freebsd-for-linux/3c509.c    Thu Sep  7 18:58:35 1995
  3. +++ netboot-freebsd/3c509.c    Wed Sep 27 20:26:11 1995
  4. @@ -526,7 +526,8 @@
  5.  
  6.      for (i = 0; is_eeprom_busy(IS_BASE) && i < MAX_EEPROMBUSY; i++);
  7.      if (i >= MAX_EEPROMBUSY) {
  8. -        printf("3c509: eeprom failed to come ready.\r\n");
  9. +            /* printf("3c509: eeprom failed to come ready.\r\n"); */
  10. +        printf("3c509: eeprom is busy.\r\n"); /* memory in EPROM is tight */
  11.          return (0);
  12.      }
  13.      return (1);
  14. diff -u -r -N netboot-freebsd-for-linux/Makefile netboot-freebsd/Makefile
  15. --- netboot-freebsd-for-linux/Makefile    Sat Sep  9 16:15:10 1995
  16. +++ netboot-freebsd/Makefile    Wed Sep 27 18:57:56 1995
  17. @@ -6,6 +6,14 @@
  18.  #    -DASK_BOOT    - Ask "Boot from Network (Y/N) ?" at startup
  19.  #    -DROMSIZE    - Size of EPROM - Must be set (even for .COM files)
  20.  #    -DRELOC        - Relocation address (usually 0x90000)
  21. +#                                                     ^^^^^^^
  22. +#                         has to be changed to 0x9A000 for loading Linux kernel
  23. +#       -DPRIORIZEBOOTPKERNEL
  24. +#                       - first honor the kernel name of the BOOTP reply
  25. +#                         before trying defaults
  26. +#       -DBOOTPKERNELONLY
  27. +#                       - never use TFTP for loading default files; the
  28. +#                         BOOTP reply has to set a valid kernel name
  29.  #
  30.  # NS8390 Options:
  31.  #    -DINCLUDE_WD    - Include Western Digital/SMC support
  32. @@ -21,7 +29,7 @@
  33.  
  34.  PROG=    nb8390.com nb3c509.com nb8390.rom nb3c509.rom
  35.  # Order is very important on the SRCS line for this prog
  36. -SRCS=    start2.S main.c misc.c bootmenu.c rpc.c
  37. +SRCS=    start2.S main.c linuxloader.c misc.c bootmenu.c rpc.c
  38.  
  39.  BINDIR=        /usr/mdec
  40.  BINMODE=    555
  41. @@ -37,7 +45,7 @@
  42.  STRIP=
  43.  
  44.  ROMSIZE=16384
  45. -RELOCADDR=0x90000
  46. +RELOCADDR=0x9A000
  47.  
  48.  .SUFFIXES:    .ro
  49.  
  50. diff -u -r -N netboot-freebsd-for-linux/Makefile.linux netboot-freebsd/Makefile.linux
  51. --- netboot-freebsd-for-linux/Makefile.linux    Sat Sep  9 00:23:05 1995
  52. +++ netboot-freebsd/Makefile.linux    Wed Sep 27 20:30:27 1995
  53. @@ -6,6 +6,14 @@
  54.  #    -DASK_BOOT    - Ask "Boot from Network (Y/N) ?" at startup
  55.  #    -DROMSIZE    - Size of EPROM - Must be set (even for .COM files)
  56.  #    -DRELOC        - Relocation address (usually 0x90000)
  57. +#                                                     ^^^^^^^
  58. +#                         has to be changed to 0x9A000 for loading Linux kernel
  59. +#       -DPRIORIZEBOOTPKERNEL
  60. +#                       - first honor the kernel name of the BOOTP reply
  61. +#                         before trying defaults
  62. +#       -DBOOTPKERNELONLY
  63. +#                       - never use TFTP for loading default files; the
  64. +#                         BOOTP reply has to set a valid kernel name
  65.  #
  66.  # NS8390 Options:
  67.  #    -DINCLUDE_WD    - Include Western Digital/SMC support
  68. @@ -22,12 +30,13 @@
  69.  
  70.  PROG=    nb8390.com nb3c509.com nb8390.rom nb3c509.rom
  71.  # Order is very important on the SRCS line for this prog
  72. -SRCS=    start2.S  main.c misc.c bootmenu.c rpc.c
  73. -OBJS=   start2.o  main.o misc.o bootmenu.o rpc.o
  74. -ROBJS=  start2.ro main.o misc.o bootmenu.o rpc.o
  75. +SRCS=    start2.S  main.c linuxloader.c misc.c bootmenu.c rpc.c
  76. +OBJS=   start2.o  main.o linuxloader.o misc.o bootmenu.o rpc.o
  77. +ROBJS=  start2.ro main.o linuxloader.o misc.o bootmenu.o rpc.o
  78.  
  79.  CFLAGS=        -O2 -DNFS -DROMSIZE=${ROMSIZE} -DRELOC=${RELOCADDR}
  80.  CFLAGS+=    -fstrength-reduce -fomit-frame-pointer -m386
  81. +CFLAGS+=        -DPRIORIZEBOOTPKERNEL
  82.  # NS8390=    -DINCLUDE_WD -DWD_DEFAULT_MEM=0xD0000
  83.  NS8390+=    -DINCLUDE_NE
  84.  # NS8390+=    -DINCLUDE_3COM -D_3COM_BASE=0x300
  85. @@ -37,7 +46,7 @@
  86.  LDFLAGS+=    -N -Ttext ${RELOCADDR} -e _start -nostdlib
  87.  
  88.  ROMSIZE=16384
  89. -RELOCADDR=0x90000
  90. +RELOCADDR=0x9A000
  91.  
  92.  .SUFFIXES:    .ro
  93.  
  94. @@ -60,26 +69,22 @@
  95.  
  96.  nb8390.rom:    makerom start2.ro ${ROBJS} ns8390.o
  97.      ${LD} ${LDFLAGS} -o nb8390.bin ${ROBJS} ns8390.o
  98. -    strip nb8390.bin
  99.      size nb8390.bin
  100.      objdump -k -q -o ${RELOCADDR} nb8390.bin >$@
  101.      ./makerom $@
  102.  
  103.  nb3c509.rom:    makerom start2.ro ${ROBJS} 3c509.o
  104.      ${LD} ${LDFLAGS} -o nb3c509.bin ${ROBJS} 3c509.o
  105. -    strip nb3c509.bin
  106.      size nb3c509.bin
  107.      objdump -k -q -o ${RELOCADDR} nb3c509.bin >$@
  108.      ./makerom $@
  109.  
  110.  nb8390.com:    makerom start2.ro ${OBJS} ns8390.o
  111.      ${LD} ${LDFLAGS} -o nb8390c.bin ${OBJS} ns8390.o
  112. -    strip nb8390c.bin
  113.      size nb8390c.bin
  114.      objdump -k -q -o ${RELOCADDR} nb8390c.bin >$@
  115.  
  116.  nb3c509.com:    start2.o ${OBJS} 3c509.o
  117.      ${LD} ${LDFLAGS} -o nb3c509c.bin ${OBJS} 3c509.o
  118. -    strip nb3c509c.bin
  119.      size nb3c509c.bin
  120.      objdump -k -q -o ${RELOCADDR} nb3c509c.bin >$@
  121. diff -u -r -N netboot-freebsd-for-linux/bootmenu.c netboot-freebsd/bootmenu.c
  122. --- netboot-freebsd-for-linux/bootmenu.c    Thu Sep  7 18:58:35 1995
  123. +++ netboot-freebsd/bootmenu.c    Tue Sep 26 11:34:42 1995
  124. @@ -7,6 +7,7 @@
  125.  **************************************************************************/
  126.  #include "netboot.h"
  127.  
  128. +extern char *linux_add_cmdline();
  129.  extern struct nfs_diskless nfsdiskless;
  130.  extern int hostnamelen;
  131.  extern unsigned long netmask;
  132. @@ -16,14 +17,14 @@
  133.  int cmd_ip(), cmd_server(), cmd_kernel(), cmd_help(), exit();
  134.  int cmd_rootfs(), cmd_swapfs(), cmd_interface(), cmd_hostname();
  135.  int cmd_netmask(), cmd_swapsize(), cmd_swapopts(), cmd_rootopts();
  136. -int cmd_aui();
  137. +int cmd_linuxcmd(),cmd_aui();
  138.  
  139.  struct bootcmds_t {
  140.      char *name;
  141.      int (*func)();
  142.      char *help;
  143.  } bootcmds[] = {
  144. -    {"?",        cmd_help,    "              this list"},
  145. +/*    {"?",        cmd_help,    "                 this list"}, */
  146.      {"help",    cmd_help,    "              this list"},
  147.      {"ip",        cmd_ip,        "<addr>          set my IP addr"},
  148.      {"server",    cmd_server,    "<addr>      set TFTP server IP addr"},
  149. @@ -35,6 +36,7 @@
  150.      {"swapsize",    cmd_swapsize,    "<nblks>   set swap size"},
  151.      {"swapopts",    cmd_swapopts,    "<options> swap mount options"},
  152.      {"rootopts",    cmd_rootopts,    "<options> root mount options"},
  153. +    {"linuxcmd",    cmd_linuxcmd,   "<cmds>    pass cmds to linux"},
  154.      {"diskboot",    exit,        "          boot from disk"},
  155.      {"autoboot",    NULL,        "          continue"},
  156.          {"trans",       cmd_aui,        "<on|off>     turn transceiver on|off"},
  157. @@ -145,11 +147,11 @@
  158.  {
  159.      if (!setip(p, &arptable[ARP_ROOTSERVER].ipaddr)) {
  160.          printf("Root filesystem is %I:%s\r\n",
  161. -            nfsdiskless.root_saddr.sin_addr,
  162. +            htonl(nfsdiskless.root_saddr.sin_addr.s_addr),
  163.              nfsdiskless.root_hostnam);
  164.      } else {
  165. -        bcopy(&arptable[ARP_ROOTSERVER].ipaddr,
  166. -            &nfsdiskless.root_saddr.sin_addr, 4);
  167. +        convert_ipaddr(&nfsdiskless.root_saddr.sin_addr,
  168. +                   &arptable[ARP_ROOTSERVER].ipaddr);
  169.          while (*p && (*p != ':')) p++;
  170.          if (*p == ':') p++;
  171.          sprintf(&nfsdiskless.root_hostnam, "%s", p);
  172. @@ -164,11 +166,11 @@
  173.  {
  174.      if (!setip(p, &arptable[ARP_SWAPSERVER].ipaddr)) {
  175.          printf("Swap filesystem is %I:%s\r\n",
  176. -            nfsdiskless.swap_saddr.sin_addr,
  177. +            htonl(nfsdiskless.swap_saddr.sin_addr.s_addr),
  178.              nfsdiskless.swap_hostnam);
  179.      } else {
  180. -        bcopy(&arptable[ARP_SWAPSERVER].ipaddr,
  181. -            &nfsdiskless.swap_saddr.sin_addr, 4);
  182. +        convert_ipaddr(&nfsdiskless.swap_saddr.sin_addr,
  183. +                   &arptable[ARP_SWAPSERVER].ipaddr);
  184.          while (*p && (*p != ':')) p++;
  185.          if (*p == ':') p++;
  186.          sprintf(&nfsdiskless.swap_hostnam, "%s", p);
  187. @@ -269,6 +271,19 @@
  188.  }
  189.  
  190.  /**************************************************************************
  191. +LINUXCMD - Pass commands to linux
  192. +**************************************************************************/
  193. +cmd_linuxcmd(p)
  194. +    char *p;
  195. +{
  196. +  if (*p)
  197. +    linux_add_cmdline(p);
  198. +  else
  199. +    printf("Linux cmdline: %s\r\n",linux_add_cmdline(p));
  200. +  return;
  201. +}
  202. +
  203. +/**************************************************************************
  204.  EXECUTE - Decode command
  205.  **************************************************************************/
  206.  execute(buf)
  207. @@ -289,7 +304,7 @@
  208.          } else
  209.              cmd++;
  210.      }
  211. -    printf("bad command - type 'help' for list\n\r");
  212. +    printf("error: `help' for list\n\r");
  213.      return(0);
  214.  }
  215.  
  216. @@ -298,13 +313,19 @@
  217.  **************************************************************************/
  218.  bootmenu()
  219.  {
  220. +    unsigned long time;
  221.      char cmd[80];
  222.      int ptr, c;
  223. -    printf("\r\n");
  224. +    linux_add_cmdline(0); /* clear linux cmdline */
  225. +    printf(" \r\n");
  226.      while (1) {
  227.          ptr = 0;
  228.          printf("boot> ");
  229.          while (ptr < 80) {
  230. +            for (time = currticks() + 90*18; !iskey() ;)
  231. +                if (time < currticks()) {
  232. +                    printf("autoboot\r\n");
  233. +                    goto done; }    
  234.              c = getchar();
  235.              if (c == '\r')
  236.                  break;
  237. @@ -322,5 +343,6 @@
  238.          printf("\r\n");
  239.          if (execute(cmd)) break;
  240.      }
  241. +    done:
  242.      eth_reset();
  243.  }
  244. diff -u -r -N netboot-freebsd-for-linux/linuxloader.c netboot-freebsd/linuxloader.c
  245. --- netboot-freebsd-for-linux/linuxloader.c    Thu Jan  1 01:00:00 1970
  246. +++ netboot-freebsd/linuxloader.c    Wed Sep 27 19:44:28 1995
  247. @@ -0,0 +1,271 @@
  248. +/**************************************************************************
  249. +Linux loader
  250. +
  251. +Author: Markus Gutschke (gutschk@math.uni-muenster.de)
  252. +  Date: Sep/95
  253. +
  254. +**************************************************************************/
  255. +
  256. +#include "netboot.h"
  257. +
  258. +#define LINUX_IMAGE_ADDR  ((char *)0x10000L)
  259. +#define XTRACMDS          ((char *)0x98000L)
  260. +#define LINUX_BOOTSECTOR  ((char *)0x90000L)
  261. +#define CMDLINEMAGIC      0xA33F
  262. +#define CMDLINE           ((unsigned short *)(LINUX_BOOTSECTOR+0x20))
  263. +#define BOOTHEADER        (((boot_header_t *)0x90200L)[-1])
  264. +#define SECTOR_SIZE       512
  265. +#define MAGIC             0xAA55
  266. +#define SETUP_MAGIC       0x5A5AAA55
  267. +
  268. +typedef struct {
  269. +  unsigned char      filler;
  270. +  unsigned char      setup_sects;
  271. +  unsigned short int root_flags;
  272. +  unsigned short int syssize;
  273. +  unsigned short int swap_dev;
  274. +  unsigned short int ram_size;
  275. +  unsigned short int vid_mode;
  276. +  unsigned short int root_dev;
  277. +  unsigned short int boot_flag;
  278. +} boot_header_t;
  279. +
  280. +char *bootphdr = (char *)0x99000L;
  281. +
  282. +char *linux_add_cmdline(char *s)
  283. +{
  284. +  if (!s) *XTRACMDS = '\000';
  285. +  else if (*s) {
  286. +    char *ptr = XTRACMDS;
  287. +    while (*ptr) ptr++;
  288. +    *ptr++ = ' ';
  289. +    sprintf(ptr,"%s",s); }
  290. +  return(XTRACMDS);
  291. +}
  292. +
  293. +static int strncmp(const unsigned char *s1,const unsigned char *s2,int n)
  294. +{
  295. +  while (n--) {
  296. +    if (*s1 != *s2) return(*s1 - *s2);
  297. +    else if (!*s1) return(0);
  298. +    else {s1++; s2++;}}
  299. +  return(0);
  300. +}
  301. +
  302. +static void linux_cmdline(char *cmdline)
  303. +{
  304. +  extern char *kernel;
  305. +  extern struct nfs_diskless nfsdiskless;
  306. +  extern unsigned long netmask;
  307. +  char   *s,*d,initargs = 0;
  308. +
  309. +  for (s = XTRACMDS; ;) { /* check for parameters to init */
  310. +    if ((!*s || *s == ' ') && (initargs&1)) initargs = 2;
  311. +    if (!*s) break;
  312. +    if (*s == '=') {initargs &= ~1; while (*s && *s != ' ') s++;}
  313. +    else if (*s++ != ' ') {
  314. +      if (!(initargs&1) && !strncmp(s-1,"vga=",4)) {
  315. +    int vga = 0;
  316. +    d = s + 3;
  317. +    if (!strncmp(d,"ASK",3)) vga = -3;
  318. +    else if (!strncmp(d,"EXTENDED",8)) vga = -2;
  319. +    else if (!strncmp(d,"NORMAL",6)) vga = -1;
  320. +    else {
  321. +      if (*d == '-') d++;
  322. +      while (*d >= '0' && *d <= '9') { vga = 10*vga+*d-'0'; d++; }
  323. +      if (s[3] == '-') vga = -vga; }
  324. +    *((unsigned short *)(LINUX_BOOTSECTOR+506)) = vga; }
  325. +      initargs |= 1; } }
  326. +  for (s = nfsdiskless.root_hostnam;*s&&s[1];s++);
  327. +  sprintf(cmdline,
  328. +      "%sBOOT_IMAGE=" /* %I: */ "%s%s%s ramdisk=0 "
  329. +      "nfsroot=%s,rsize=%d,wsize=%d,%s,%s "
  330. +      "nfsaddrs=%I:%I:%I:%I:%s %s",
  331. +      initargs&2 ? "" : "auto ",
  332. +      /* htonl(nfsdiskless.root_saddr.sin_addr.s_addr), */
  333. +      nfsdiskless.root_hostnam,
  334. +      *s == '/' ? "" : "/",
  335. +      *kernel == '/' ? kernel + 1 : kernel,
  336. +      nfsdiskless.root_hostnam,
  337. +      nfsdiskless.root_args.rsize,
  338. +      nfsdiskless.root_args.wsize,
  339. +      nfsdiskless.root_args.flags & NFSMNT_SOFT ? "soft" : "hard",
  340. +      nfsdiskless.root_args.flags & NFSMNT_INT ? "intr" : "nointr",
  341. +      arptable[ARP_CLIENT].ipaddr,
  342. +      htonl(nfsdiskless.root_saddr.sin_addr.s_addr),
  343. +      arptable[ARP_GATEWAY].ipaddr,
  344. +      htonl(netmask),
  345. +      nfsdiskless.my_hostnam,
  346. +      XTRACMDS);
  347. +  for (s = d = cmdline; ;) { /* remove multiple space characters */
  348. +    if (*s == ' ') {while (s[1] ==  ' ') s++; if (!s[1]) s++;}
  349. +    if (!(*d++ = *s++)) break; }
  350. +  *((unsigned short *)(LINUX_BOOTSECTOR+504)) = 0;      /* no ramdisk */
  351. +  *((unsigned short *)(LINUX_BOOTSECTOR+508)) = 0x00FF; /* mount root on nfs */
  352. +  return;
  353. +}
  354. +
  355. +int load_linux(int root_mount_port,int swap_mount_port,
  356. +           int root_nfs_port,char *kernel_handle)
  357. +{
  358. +  extern int   jmp_bootmenu[10];
  359. +  extern char *kernel;
  360. +  extern void  start_linux(void);
  361. +  int          err, offset, read_size, count;
  362. +  char        *addr,*cmdline;
  363. +  
  364. +  /* Linux boot sector and setup code has to be loaded to address 0x90000 */
  365. +  if ((err = nfs_read(ARP_ROOTSERVER, root_nfs_port, kernel_handle, 0,
  366. +              SECTOR_SIZE,LINUX_BOOTSECTOR)) != SECTOR_SIZE) {
  367. +  readerr:
  368. +    printf("Unable to read %s: ",kernel);
  369. +    nfs_err(err);
  370. +  bootmenu:
  371. +    longjmp(jmp_bootmenu,1);
  372. +  }
  373. +  if (BOOTHEADER.boot_flag != MAGIC)
  374. +    return(0);
  375. +  /* Boot sector contains size information for setup code */
  376. +  offset    = SECTOR_SIZE;
  377. +  read_size = SECTOR_SIZE;
  378. +  count     = BOOTHEADER.setup_sects;
  379. +  while (count--) {
  380. +    if ((err = nfs_read(ARP_ROOTSERVER, root_nfs_port, kernel_handle,
  381. +            offset, read_size, LINUX_BOOTSECTOR + offset)) !=
  382. +    read_size) {
  383. +      if (err < 0) {
  384. +    goto readerr; }
  385. +      goto bootmenu; }
  386. +    offset += err; }
  387. +  for (count = SECTOR_SIZE-4; *(unsigned int *)(LINUX_BOOTSECTOR-
  388. +                        SECTOR_SIZE+offset+count) !=
  389. +     SETUP_MAGIC;)
  390. +    if (count-- < 0)
  391. +      goto bootmenu;
  392. +  /* Construct Linux's command line */
  393. +  cmdline = LINUX_BOOTSECTOR + offset;
  394. +  CMDLINE[0] = CMDLINEMAGIC;
  395. +  CMDLINE[1] = cmdline - LINUX_BOOTSECTOR;
  396. +  linux_cmdline(cmdline);
  397. +  while (*cmdline) putchar(*cmdline++);
  398. +  printf("\r\n");
  399. +  /* Kernel image will be loaded to address 0x10000; it will automatically
  400. +     be relocated to 0x100000 by the setup code */
  401. +  read_size = NFS_READ_SIZE;
  402. +  count = 16*BOOTHEADER.syssize;
  403. +  addr  = LINUX_IMAGE_ADDR;
  404. +  printf("Loading compressed kernel image");
  405. +  while (count >= 16) {
  406. +    if (read_size > count) read_size = count;
  407. +    if ((err = nfs_read(ARP_ROOTSERVER, root_nfs_port, kernel_handle,
  408. +            offset, read_size, addr)) != read_size) {
  409. +      if (err < 0) goto readerr;
  410. +      if (read_size-err >= 16)
  411. +    goto bootmenu; }
  412. +    if (!(offset & 0x3C00)) putchar('.');
  413. +    offset += err;
  414. +    count  -= err;
  415. +    addr += err; }
  416. +  /* Linux wants to mount swapspace and rootfilesystem by itself; so unmount */
  417. +  /* all mounted NFS filesystems */
  418. +  nfs_umountall(ARP_ROOTSERVER, root_mount_port);
  419. +  if (arptable[ARP_SWAPSERVER].ipaddr &&
  420. +      arptable[ARP_SWAPSERVER].ipaddr != arptable[ARP_ROOTSERVER].ipaddr)
  421. +    nfs_umountall(ARP_SWAPSERVER, swap_mount_port);
  422. +  /* Linux kernel has to be started in real-mode */
  423. +  printf(" \r\nStarting...\r\n");
  424. +  start_linux();
  425. +  /* printf("*** %s execute failure ***\n",kernel); */
  426. +  goto bootmenu;
  427. +}
  428. +
  429. +int linux_tftp(int block,unsigned char *data,int len)
  430. +{
  431. +  extern int   jmp_bootmenu[10];
  432. +  static enum {Munknown,Mlinear,Mtagged,Mreading} mode = Munknown;
  433. +  static unsigned char *addr,*execaddr,*hdraddr;
  434. +  static struct imgheader {
  435. +    unsigned long magic;
  436. +    unsigned long flags;
  437. +    struct {unsigned short bx,ds; } location;
  438. +    struct {unsigned short ip,cs; } execaddr; } *imgheader;
  439. +  static struct segheader {
  440. +    unsigned long flags;
  441. +    unsigned long loadaddr;
  442. +    unsigned long imglength;
  443. +    unsigned long memlength; } *segheader;
  444. +  static int imglen,headerlen;
  445. +  static unsigned char *last0,*last1;
  446. +  static int lastchunk;
  447. +
  448. +  if (block == 1) {
  449. +    lastchunk = 0;
  450. +    if (*((unsigned long *)data) == 0x1B031336l) {
  451. +      imgheader = (struct imgheader *)((unsigned long)
  452. +                       (((unsigned short *)data)[5])*16 +
  453. +                       ((unsigned short *)data)[4]); 
  454. +      segheader = (struct segheader *)imgheader;
  455. +      last1 = (last0 = (unsigned char *)imgheader) + 0x200;
  456. +      bcopy(data,imgheader,len);
  457. +      headerlen = (imgheader->flags & 0x0F)*4 +
  458. +              (imgheader->flags & 0xF0)/4;
  459. +      execaddr = *(unsigned char **)&imgheader->execaddr;
  460. +      hdraddr =  *(unsigned char **)&imgheader->location;
  461. +      mode = Mtagged;
  462. +      return(1); }
  463. +    else if (((unsigned short *)data)[255] == 0xAA55) {
  464. +      bcopy(data,(char *)0x7C00,len);
  465. +      execaddr = hdraddr = (unsigned char *)0x07C00000l;
  466. +      mode = Mlinear;
  467. +      addr = (char *)0x10000l;
  468. +      return(1); }
  469. +    return(0); }
  470. +  else {
  471. +    int i,datalen = len;
  472. +    if (mode == Mlinear) {
  473. +      bcopy(data,addr,datalen);
  474. +      if ((unsigned long)(addr += 0x200) >= 0x98000l)
  475. +    addr = (unsigned char *)0x100000l; }
  476. +    else if (mode == Mtagged) {
  477. +    tag:
  478. +      do {
  479. +    if (lastchunk)
  480. +      goto launch;
  481. +    segheader = (struct segheader *)((char *)segheader + headerlen);
  482. +    imglen = segheader->imglength;
  483. +    headerlen = (segheader->flags & 0x0F)*4 +
  484. +      (segheader->flags & 0xF0)/4;
  485. +    if ((i = segheader->flags & 0x03000000l) == 0)
  486. +      addr = (unsigned char *)segheader->loadaddr;
  487. +    else if (i == 0x01000000l)
  488. +      addr = last1 + segheader->loadaddr;
  489. +    else if (i == 0x02000000l) {
  490. +      extern unsigned short memsize(void);
  491. +      addr = (unsigned char *)(memsize()*1024l+0x100000l)
  492. +             - segheader->loadaddr; }
  493. +    else
  494. +      addr = last0 - segheader->loadaddr;
  495. +    last1 = (last0 = addr) + segheader->memlength;
  496. +    if (segheader->flags & 0x04000000l) lastchunk = 1;
  497. +      } while (imglen <= 0);
  498. +      mode = Mreading;
  499. +      goto reading; }
  500. +    else if (mode == Mreading) {
  501. +    reading:
  502. +      if ((i = imglen) > datalen) i = datalen;
  503. +      bcopy(data,addr,i);
  504. +      datalen -= i; data += i;
  505. +      addr += i;
  506. +      if ((imglen -= i) <= 0) {
  507. +    mode = Mtagged;
  508. +    if (datalen > 0) goto tag; }
  509. +      return(1); }
  510. +    else
  511. +      return(0); }
  512. +  if (len < 0x200) {
  513. +    extern void xstart(char *,char *,char *);
  514. +  launch:
  515. +    xstart(execaddr,hdraddr,(char *)0x99000000l);
  516. +    longjmp(jmp_bootmenu,1); }
  517. +  return(1);
  518. +}
  519. diff -u -r -N netboot-freebsd-for-linux/main.c netboot-freebsd/main.c
  520. --- netboot-freebsd-for-linux/main.c    Fri Sep  8 10:59:08 1995
  521. +++ netboot-freebsd/main.c    Wed Sep 27 20:26:44 1995
  522. @@ -28,6 +28,10 @@
  523.  extern    int packetlen, rpc_id;
  524.  char    broadcast[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
  525.  
  526. +extern int load_linux(int root_mount_port,int swap_mount_port,
  527. +              int root_nfs_port,char *kernel_handle);
  528. +extern int linux_tftp(int block,unsigned char *data,int len);
  529. +
  530.  /**************************************************************************
  531.  MAIN - Kick off routine
  532.  **************************************************************************/
  533. @@ -37,6 +41,7 @@
  534.  
  535.  main()
  536.  {
  537. +    extern char *linux_add_cmdline();
  538.      int c;
  539.      char *p;
  540.      extern char edata[], end[];
  541. @@ -56,13 +61,14 @@
  542.      }
  543.  #endif
  544.      gateA20();
  545. -    printf("\r\nBOOTP/TFTP/NFS bootstrap loader    ESC for menu\n\r");
  546. -    printf("\r\nSearching for adapter...");
  547. +    printf("\r\nBOOTP/TFTP/NFS bootstrap loader    ESC for menu\n\r"
  548. +           "\r\nSearching for adapter...");
  549.      if (!eth_probe()) {
  550.          printf("No adapter found.\r\n");
  551.          exit(0);
  552.      }
  553.      kernel = DEFAULT_BOOTFILE;
  554. +    linux_add_cmdline(0); /* clear linux cmdline */
  555.      while (1) {
  556.          if (setjmp(jmp_bootmenu))
  557.              bootmenu();
  558. @@ -72,6 +78,37 @@
  559.  }
  560.  
  561.  /**************************************************************************
  562. +DOMOUNT - Try to mount FS
  563. +**************************************************************************/
  564. +domount(char *s,int *port,int *mount_port,char *hostnam,char *fh,int arpserver,
  565. +                struct sockaddr_in *in_saddr,struct nfs_args *args,char *fnam,
  566. +                char *newfh)
  567. +{
  568. +    int err;
  569. +    *port = rpclookup(arpserver, PROG_NFS, 2);
  570. +    *mount_port = rpclookup(arpserver, PROG_MOUNT, 1);
  571. +    if ((*port == -1) || (*mount_port == -1)) {
  572. +        printf("Unable to get %s NFS/MOUNT ports\r\n",s);
  573. +    bootmenu:
  574. +        longjmp(jmp_bootmenu,1); }
  575. +    if (err = nfs_mount(arpserver, *mount_port,    hostnam, fh)) {
  576. +        printf("Unable to mount %s filesystem: ",s);
  577. +    nfserr:
  578. +        nfs_err(err);
  579. +        goto bootmenu; }
  580. +    in_saddr->sin_len = sizeof(struct sockaddr_in);
  581. +    in_saddr->sin_family = AF_INET;
  582. +    in_saddr->sin_port = htons(*port);
  583. +    in_saddr->sin_addr.s_addr = htonl(arptable[arpserver].ipaddr);
  584. +    args->timeo = 10;
  585. +    args->retrans = 100;
  586. +    if (err = nfs_lookup(arpserver,*port,fh,fnam,newfh)) {
  587. +        printf("Unable to open %s: ",fnam);
  588. +        goto nfserr; }
  589. +    return;
  590. +}
  591. +
  592. +/**************************************************************************
  593.  LOAD - Try to get booted
  594.  **************************************************************************/
  595.  load()
  596. @@ -104,6 +141,7 @@
  597.          printf("\r\nSearching for server...\r\n");
  598.          if (!bootp()) {
  599.              printf("No Server found.\r\n");
  600. +        bootmenu:
  601.              longjmp(jmp_bootmenu,1);
  602.          }
  603.      }
  604. @@ -117,16 +155,31 @@
  605.  #endif
  606.  
  607.          /* Now use TFTP to load configuration file */
  608. +#if defined(PRIORIZEBOOTPKERNEL) && !defined(BOOTPKERNELONLY)
  609. +    printf(" \r\nLoading %s... ",kernel);
  610. +    if (!tftp(kernel)) {
  611. +#endif
  612. +#ifndef BOOTPKERNELONLY
  613.      sprintf(cfg,"cfg.%I",arptable[ARP_CLIENT].ipaddr);
  614. -    printf("Loading %s...\r\n",cfg);
  615. +    printf(" \r\nLoading %s... ",cfg);
  616.      if (!tftp(cfg)) {
  617.          sprintf(cfg,"/tftpboot/cfg.%I",arptable[ARP_CLIENT].ipaddr);
  618. -        printf("Loading %s...\r\n",cfg);
  619. +        printf(" \r\nLoading %s... ",cfg);
  620.          if (!tftp(cfg)) {
  621. -            printf("Unable to load config file.\r\n");
  622. -            longjmp(jmp_bootmenu,1);
  623. -        }
  624. -    }
  625. +#endif
  626. +#ifndef PRIORIZEBOOTPKERNEL
  627. +            printf(" \r\nLoading %s... ",kernel);
  628. +            if (!tftp(kernel)) {
  629. +#endif
  630. +                printf("Unable to load config file.\r\n");
  631. +                goto bootmenu;
  632. +#if !defined(PRIORIZEBOOTPKERNEL) || \
  633. +         defined(PRIORIZEBOOTPKERNEL) && !defined(BOOTPKERNELONLY)
  634. + }
  635. +#endif
  636. +#ifndef BOOTPKERNELONLY
  637. +    }    }
  638. +#endif
  639.  
  640.  #ifdef MDEBUG
  641.      printf("\n=>>"); getchar();
  642. @@ -149,7 +202,7 @@
  643.          /* Check to make sure we've got a rootfs */
  644.      if (!arptable[ARP_ROOTSERVER].ipaddr) {
  645.          printf("No ROOT filesystem server!\r\n");
  646. -        longjmp(jmp_bootmenu,1);
  647. +        goto bootmenu;
  648.      }
  649.  
  650.          /* Fill in nfsdiskless.myif */
  651. @@ -179,79 +232,36 @@
  652.          /* Lookup NFS/MOUNTD ports for SWAP using PORTMAP */
  653.      if (arptable[ARP_SWAPSERVER].ipaddr) {
  654.          char swapfs_fh[32], swapfile[32];
  655. -        swap_nfs_port = rpclookup(ARP_SWAPSERVER, PROG_NFS, 2);
  656. -        swap_mount_port = rpclookup(ARP_SWAPSERVER, PROG_MOUNT, 1);
  657. -        if ((swap_nfs_port == -1) || (swap_mount_port == -1)) {
  658. -            printf("Unable to get SWAP NFS/MOUNT ports\r\n");
  659. -            longjmp(jmp_bootmenu,1);
  660. -        }
  661. -        if (err = nfs_mount(ARP_SWAPSERVER, swap_mount_port,
  662. -            nfsdiskless.swap_hostnam, &swapfs_fh)) {
  663. -            printf("Unable to mount SWAP filesystem: ");
  664. -            nfs_err(err);
  665. -            longjmp(jmp_bootmenu,1);
  666. -        }
  667.          sprintf(swapfile,"swap.%I",arptable[ARP_CLIENT].ipaddr);
  668. -        if (err = nfs_lookup(ARP_SWAPSERVER, swap_nfs_port,
  669. -            &swapfs_fh, swapfile, &nfsdiskless.swap_fh)) {
  670. -            printf("Unable to open %s: ",swapfile);
  671. -            nfs_err(err);
  672. -            longjmp(jmp_bootmenu,1);
  673. -        }
  674. -        nfsdiskless.swap_saddr.sin_len = sizeof(struct sockaddr_in);
  675. -        nfsdiskless.swap_saddr.sin_family = AF_INET;
  676. -        nfsdiskless.swap_saddr.sin_port = htons(swap_nfs_port);
  677. -        nfsdiskless.swap_saddr.sin_addr.s_addr =
  678. -            htonl(arptable[ARP_SWAPSERVER].ipaddr);
  679. -            nfsdiskless.swap_args.timeo = 10;
  680. -            nfsdiskless.swap_args.retrans = 100;
  681. -    }
  682. +        domount("SWAP",&swap_nfs_port,&swap_mount_port,nfsdiskless.swap_hostnam,
  683. +                        swapfs_fh,ARP_SWAPSERVER,&nfsdiskless.swap_saddr,
  684. +                        &nfsdiskless.swap_args,swapfile,nfsdiskless.swap_fh); }
  685.  
  686.          /* Lookup NFS/MOUNTD ports for ROOT using PORTMAP */
  687. -    root_nfs_port = rpclookup(ARP_ROOTSERVER, PROG_NFS, 2);
  688. -    root_mount_port = rpclookup(ARP_ROOTSERVER, PROG_MOUNT, 1);
  689. -    if ((root_nfs_port == -1) || (root_mount_port == -1)) {
  690. -        printf("Unable to get ROOT NFS/MOUNT ports\r\n");
  691. -        longjmp(jmp_bootmenu,1);
  692. -    }
  693. -    if (err = nfs_mount(ARP_ROOTSERVER, root_mount_port,
  694. -        nfsdiskless.root_hostnam, &nfsdiskless.root_fh)) {
  695. -        printf("Unable to mount ROOT filesystem: ");
  696. -        nfs_err(err);
  697. -        longjmp(jmp_bootmenu,1);
  698. -    }
  699. -    nfsdiskless.root_saddr.sin_len = sizeof(struct sockaddr_in);
  700. -    nfsdiskless.root_saddr.sin_family = AF_INET;
  701. -    nfsdiskless.root_saddr.sin_port = htons(root_nfs_port);
  702. -    nfsdiskless.root_saddr.sin_addr.s_addr =
  703. -        htonl(arptable[ARP_ROOTSERVER].ipaddr);
  704. -        nfsdiskless.root_args.timeo = 10;
  705. -        nfsdiskless.root_args.retrans = 100;
  706. +    domount("ROOT",&root_nfs_port,&root_mount_port,nfsdiskless.root_hostnam,
  707. +                    nfsdiskless.root_fh,ARP_ROOTSERVER,&nfsdiskless.root_saddr,
  708. +                    &nfsdiskless.root_args,*kernel == '/' ? kernel+1 : kernel,
  709. +                    kernel_handle);
  710.      nfsdiskless.root_time = 0;
  711.  
  712. -    if (err = nfs_lookup(ARP_ROOTSERVER, root_nfs_port,
  713. -        &nfsdiskless.root_fh, *kernel == '/' ? kernel+1 : kernel,
  714. -        &kernel_handle)) {
  715. -        printf("Unable to open %s: ",kernel);
  716. -        nfs_err(err);
  717. -        longjmp(jmp_bootmenu,1);
  718. -    }
  719. -
  720.          /* Load the kernel using NFS */
  721.      printf("Loading %s...\r\n",kernel);
  722.      if ((err = nfs_read(ARP_ROOTSERVER, root_nfs_port, &kernel_handle, 0,
  723.          sizeof(struct exec), &head)) < 0) {
  724.          printf("Unable to read %s: ",kernel);
  725. +  nfserr:
  726.          nfs_err(err);
  727. -        longjmp(jmp_bootmenu,1);
  728. +        goto bootmenu;
  729.      }
  730. -    if (N_BADMAG(head)) {
  731. +    if (N_BADMAG(head) &&
  732. +        !load_linux(root_mount_port,swap_mount_port,
  733. +            root_nfs_port,kernel_handle)) {
  734.          printf("Bad executable format!\r\n");
  735. -        longjmp(jmp_bootmenu, 1);
  736. +        goto bootmenu;
  737.      }
  738.      loadpoint = (char *)0x100000;
  739.      offset = N_TXTOFF(head);
  740. -    printf("text=0x%X, ",head.a_text);
  741. +    /* printf("text=0x%X, ",head.a_text); */
  742.      while (head.a_text > 0) {
  743.          read_size = head.a_text > NFS_READ_SIZE ?
  744.                  NFS_READ_SIZE : head.a_text;
  745. @@ -259,10 +269,10 @@
  746.              &kernel_handle, offset, read_size, loadpoint)) !=
  747.                  read_size) {
  748.              if (err < 0) {
  749. -                printf("Unable to read text: ");
  750. +              /* printf("Unable to read text: "); */
  751.                  nfs_err(err);
  752.              }
  753. -            longjmp(jmp_bootmenu, 1);
  754. +            goto bootmenu;
  755.          }
  756.          loadpoint += err;
  757.          head.a_text -= err;
  758. @@ -270,7 +280,7 @@
  759.      }
  760.      while (((int)loadpoint) & CLOFSET)
  761.          *(loadpoint++) = 0;
  762. -    printf("data=0x%X, ",head.a_data);
  763. +    /* printf("data=0x%X, ",head.a_data); */
  764.      while (head.a_data > 0) {
  765.          read_size = head.a_data > NFS_READ_SIZE ?
  766.                  NFS_READ_SIZE : head.a_data;
  767. @@ -278,19 +288,19 @@
  768.              &kernel_handle, offset, read_size, loadpoint)) !=
  769.                  read_size) {
  770.              if (err < 0) {
  771. -                printf("Unable to read data: ");
  772. +              /* printf("Unable to read data: "); */
  773.                  nfs_err(err);
  774.              }
  775. -            longjmp(jmp_bootmenu, 1);
  776. +            goto bootmenu;
  777.          }
  778.          loadpoint += err;
  779.          head.a_data -= err;
  780.          offset += err;
  781.      }
  782. -    printf("bss=0x%X, ",head.a_bss);
  783. +    /* printf("bss=0x%X, ",head.a_bss); */
  784.      while(head.a_bss--) *(loadpoint++) = 0;
  785.  
  786. -    printf("entry=0x%X.\n\r",head.a_entry);
  787. +    /* printf("entry=0x%X.\n\r",head.a_entry); */
  788.  
  789.          /* Jump to kernel */
  790.      bootinfo.bi_version = BOOTINFO_VERSION;
  791. @@ -298,7 +308,7 @@
  792.      bootinfo.bi_nfs_diskless = &nfsdiskless;
  793.      kernelentry = (void *)(head.a_entry & 0x00FFFFFF);
  794.      (*kernelentry)(0,NODEV,0,0,0,&bootinfo,0,0,0);
  795. -    printf("*** %s execute failure ***\n",kernel);
  796. +    /* printf("*** %s execute failure ***\n",kernel); */
  797.  }
  798.  
  799.  /**************************************************************************
  800. @@ -406,42 +416,50 @@
  801.      struct    tftp_t    *tr;
  802.      int retry = MAX_TFTP_RETRIES;
  803.      static unsigned short isocket = 2000;
  804. -    unsigned short osocket = TFTP;
  805. -    unsigned short len, block=1;
  806. +    unsigned short osocket;
  807. +    unsigned short len,sndlen,block=1,i;
  808.      struct tftp_t tp;
  809.      int code;
  810.      isocket++;
  811.      tp.opcode = htons(TFTP_RRQ);
  812. -    len = (sprintf((char *)tp.u.rrq,"%s%c%s",name,0,"octet")
  813. -        - ((char *)&tp)) + 1;
  814. -    while(retry--) {
  815. -        if (!udp_transmit(arptable[ARP_SERVER].ipaddr, isocket, osocket,
  816. -            len, &tp)) return(0);
  817. -        if (await_reply(AWAIT_TFTP, isocket, NULL)) {
  818. +    sndlen = len = (sprintf((char *)tp.u.rrq,"%s%c%s",name,0,"octet")
  819. +                         - ((char *)&tp)) + 1;
  820. +    while(block == 1 && retry--) {
  821. +        if (!udp_transmit(arptable[ARP_SERVER].ipaddr, isocket, TFTP,
  822. +                                            sndlen, &tp)) return(0);
  823. +        while (await_reply(AWAIT_TFTP, isocket, NULL)) {
  824.              tr = (struct tftp_t *)&packet[ETHER_HDR_SIZE];
  825.              if (tr->opcode == ntohs(TFTP_ERROR)) {
  826.                  printf("TFTP error %d (%s)\r\n",
  827. -                    ntohs(tr->u.err.errcode),
  828. -                    tr->u.err.errmsg);
  829. -                return(0);
  830. -            }            /* ACK PACKET */
  831. +                             ntohs(tr->u.err.errcode),
  832. +                             tr->u.err.errmsg);
  833. +                return(0); } /* ACK PACKET */
  834.              if (tr->opcode != ntohs(TFTP_DATA)) return(0);
  835. +            osocket = ntohs(tr->udp.src);
  836.              tp.opcode = htons(TFTP_ACK);
  837.              tp.u.ack.block = tr->u.data.block;
  838. -            udp_transmit(arptable[ARP_SERVER].ipaddr, isocket,
  839. -                osocket, TFTP_MIN_PACKET_SIZE, &tp);
  840.              len = ntohs(tr->udp.len) - sizeof(struct udphdr) - 4;
  841. -            if (len >= 512) {
  842. -                printf("Config file too large.\r\n");
  843. -                config_buffer[0] = 0;
  844. -                return(0);
  845. -            } else {
  846. -                bcopy(tr->u.data.download, config_buffer, len);
  847. -                config_buffer[len] = 0;
  848. -            }
  849. -            return(1);
  850. -        }
  851. -    }
  852. +            i = ntohs(tr->u.data.block);
  853. +            if (i < block) continue;
  854. +            else if (i > block) return(0);
  855. +            udp_transmit(arptable[ARP_SERVER].ipaddr, isocket,
  856. +                                     osocket, sndlen = TFTP_MIN_PACKET_SIZE, &tp);
  857. +            if (block == 1) {
  858. +                if (len >= 512) {
  859. +                    if (((unsigned short *)tr->u.data.download)[255] != 0xAA55 &&
  860. +                            *((unsigned long *)tr->u.data.download) != 0x1B031336l) {
  861. +                        config_buffer[0] = 0;
  862. +                        return(0); }
  863. +                    else
  864. +                        printf("Tagged file format"); }
  865. +                else {
  866. +                    bcopy(tr->u.data.download, config_buffer, len);
  867. +                    config_buffer[len] = 0;
  868. +                    return(1); } }
  869. +            if (!linux_tftp(block++,tr->u.data.download,len)) {
  870. +                return(0); }
  871. +            if (len < 512)
  872. +                return(0); } }
  873.      return(0);
  874.  }
  875.  
  876. @@ -462,8 +480,10 @@
  877.      while(retry--) {
  878.          udp_transmit(IP_BROADCAST, 0, BOOTP_SERVER,
  879.              sizeof(struct bootp_t), &bp);
  880. -        if (await_reply(AWAIT_BOOTP, 0, NULL))
  881. -            return(1);
  882. +        if (await_reply(AWAIT_BOOTP, 0, NULL)) {
  883. +            extern char *bootphdr;
  884. +            bcopy(&packet[ETHER_HDR_SIZE],bootphdr,packetlen-ETHER_HDR_SIZE);
  885. +            return(1); }
  886.          bp.bp_secs = htons((currticks()-starttime)/20);
  887.      }
  888.      return(0);
  889. @@ -573,26 +593,18 @@
  890.      if (bcompare(p, rfc1048_cookie, 4)) { /* RFC 1048 header */
  891.          p += 4;
  892.          while(p < end) {
  893. -            switch (*p) {
  894. -            case RFC1048_PAD:
  895. -                p++;
  896. -                continue;
  897. -            case RFC1048_END:
  898. -                p = end;
  899. -                continue;
  900. -            case RFC1048_NETMASK:
  901. -                bcopy(p+2,&netmask,4);
  902. -                break;
  903. -            case RFC1048_HOSTNAME:
  904. -                bcopy(p+2, &nfsdiskless.my_hostnam, TAG_LEN(p));
  905. -                hostnamelen = (TAG_LEN(p) + 3) & ~3;
  906. -                break;
  907. -            default:
  908. +            unsigned char c = *p;
  909. +            if (c == RFC1048_PAD) {p++; continue;}
  910. +            else if (c == RFC1048_END) {p = end; continue; }
  911. +            else if (c == RFC1048_NETMASK) {bcopy(p+2,&netmask,4); }
  912. +            else if (c == RFC1048_HOSTNAME) {
  913. +                bcopy(p+2,&nfsdiskless.my_hostnam,TAG_LEN(p));
  914. +                hostnamelen = (TAG_LEN(p)+3)&~3; }
  915. +            else {
  916.                  printf("Unknown RFC1048-tag ");
  917.                  for(q=p;q<p+2+TAG_LEN(p);q++)
  918.                      printf("%x ",*q);
  919. -                printf("\n\r");
  920. -            }
  921. +                printf("\n\r"); }
  922.              p += TAG_LEN(p) + 2;
  923.          }
  924.      }
  925. diff -u -r -N netboot-freebsd-for-linux/netboot.h netboot-freebsd/netboot.h
  926. --- netboot-freebsd-for-linux/netboot.h    Thu Sep  7 19:54:14 1995
  927. +++ netboot-freebsd/netboot.h    Tue Sep 26 16:55:45 1995
  928. @@ -46,7 +46,7 @@
  929.  #endif
  930.  
  931.  #ifndef TIMEOUT            /* Inter-packet retry in ticks 18/sec */
  932. -#define TIMEOUT            20
  933. +#define TIMEOUT            30
  934.  #endif
  935.  
  936.  #ifndef NULL
  937. @@ -129,6 +129,7 @@
  938.  #define PORTMAP_LOOKUP    3
  939.  
  940.  #define MOUNT_ADDENTRY    1
  941. +#define MOUNT_UMNTALL   4
  942.  #define NFS_LOOKUP    4
  943.  #define NFS_READ    6
  944.  
  945. diff -u -r -N netboot-freebsd-for-linux/ns8390.c netboot-freebsd/ns8390.c
  946. --- netboot-freebsd-for-linux/ns8390.c    Sat Sep  9 00:23:55 1995
  947. +++ netboot-freebsd/ns8390.c    Tue Sep 26 16:57:22 1995
  948. @@ -310,7 +310,7 @@
  949.              }
  950.          }
  951.          eth_pio_read(0, romdata, 16);
  952. -        printf("\r\nNE1000/NE2000 base 0x%x, addr ", eth_nic_base);
  953. +        printf("\r\nNE*000 base 0x%x, addr ", eth_nic_base);
  954.          for (i=0; i<6; i++) {
  955.              printf("%b",(int)(arptable[ARP_CLIENT].node[i] = romdata[i
  956.                  + ((eth_flags & FLAG_16BIT) ? i : 0)]));
  957. diff -u -r -N netboot-freebsd-for-linux/rpc.c netboot-freebsd/rpc.c
  958. --- netboot-freebsd-for-linux/rpc.c    Thu Sep  7 18:58:37 1995
  959. +++ netboot-freebsd/rpc.c    Wed Sep 27 20:14:38 1995
  960. @@ -80,6 +80,37 @@
  961.      return(-1);
  962.  }
  963.  
  964. +/***************************************************************************
  965. +
  966. +NFS_UMNTALL:  Unmount all NFS Filesystem
  967. +
  968. +***************************************************************************/
  969. +nfs_umountall(server, port)
  970. +    int server;
  971. +    int port;
  972. +{
  973. +    struct    rpc_t buf, *rpc;
  974. +    char    *rpcptr;
  975. +    int retries = MAX_RPC_RETRIES;
  976. +    rpcptr = sprintf(&buf.u.data,"%L%L%L%L%L%L%L%L%L%S%L%L%L%L%L%L%L",
  977. +        rpc_id, MSG_CALL, 2, PROG_MOUNT, 1, MOUNT_UMNTALL,
  978. +        1, hostnamelen + 28,0,&nfsdiskless.my_hostnam,0,0,2,0,0,0,0);
  979. +    while(retries--) {
  980. +        udp_transmit(arptable[server].ipaddr, RPC_SOCKET,
  981. +            port, rpcptr - (char *)&buf, &buf);
  982. +        if (await_reply(AWAIT_RPC, rpc_id, NULL)) {
  983. +            rpc = (struct rpc_t *)&packet[ETHER_HDR_SIZE];
  984. +            if (rpc->u.reply.rstatus || rpc->u.reply.verifier ||
  985. +                rpc->u.reply.astatus || rpc->u.reply.data[0]) {
  986. +                rpc_err(rpc);
  987. +                return(-(ntohl(rpc->u.reply.data[0])));
  988. +            } else {
  989. +                return(0);
  990. +            }
  991. +        }
  992. +    }
  993. +    return(-1);
  994. +}
  995.  
  996.  /***************************************************************************
  997.  
  998. @@ -151,7 +182,7 @@
  999.              } else {
  1000.                  rlen = ntohl(rpc->u.reply.data[18]);
  1001.                  if (len < rlen) rlen = len;
  1002. -                if (len > rlen) printf("short read\r\n");
  1003. +/*                if (len > rlen) printf("short read\r\n"); */
  1004.                  bcopy(&rpc->u.reply.data[19], buffer, rlen);
  1005.                  return(rlen);
  1006.              }
  1007. @@ -178,10 +209,11 @@
  1008.  nfs_err(err)
  1009.      int err;
  1010.  {
  1011. -    err = -err;
  1012. -    if (err == NFSERR_PERM)        printf("Not owner");
  1013. -    else if (err == NFSERR_NOENT)     printf("No such file or directory");
  1014. -    else if (err == NFSERR_ACCES)    printf("Permission denied");
  1015. -    else printf("Error %d",err);
  1016. -    printf("\r\n");
  1017. +    printf(
  1018. +#ifndef TIGHTMEMORY
  1019. +                 err == -NFSERR_PERM ? "Not owner\r\n" :
  1020. +                 err == -NFSERR_NOENT ? "No such file or directory\r\n" :
  1021. +                 err == -NFSERR_ACCES ? "Permission denied\r\n" :
  1022. +#endif
  1023. +                 "Error %d\n\n",-err);
  1024.  }
  1025. diff -u -r -N netboot-freebsd-for-linux/start2.S netboot-freebsd/start2.S
  1026. --- netboot-freebsd-for-linux/start2.S    Fri Sep  8 11:04:11 1995
  1027. +++ netboot-freebsd/start2.S    Wed Sep 27 19:17:53 1995
  1028. @@ -1,5 +1,9 @@
  1029. -
  1030. -#define STACKADDR    0xe000    /* Needs to be end of bss + stacksize */
  1031. +/* Stack needs to be end of bss + stacksize, but not exceeding lower 640kB */
  1032. +#if RELOC+0xE000 > 0xA0000
  1033. +#define STACKADDR    (0xA0000-RELOC)
  1034. +#else
  1035. +#define STACKADDR    0xE000
  1036. +#endif
  1037.  #define KERN_CODE_SEG    0x08
  1038.  #define KERN_DATA_SEG    0x10
  1039.  #define REAL_MODE_SEG    0x18
  1040. @@ -89,6 +93,7 @@
  1041.  #endif
  1042.  1:
  1043.      nop
  1044. +
  1045.      mov    %cs,%ax
  1046.      mov    %ax,%ds
  1047.      mov    %ax,%es
  1048. @@ -98,6 +103,7 @@
  1049.      mov    %eax,%esp
  1050.      opsize
  1051.      call    _real_to_prot
  1052. +
  1053.      call    _main
  1054.      .globl    _exit
  1055.      .globl    exit
  1056. @@ -125,8 +131,8 @@
  1057.      .globl    currticks
  1058.  currticks:
  1059.  _currticks:
  1060. -    push    %ebp
  1061. -    mov    %esp,%ebp
  1062. +/*    push    %ebp
  1063. +    mov    %esp,%ebp */
  1064.      push    %ecx
  1065.      push    %edx
  1066.      xor    %edx,%edx
  1067. @@ -141,7 +147,7 @@
  1068.      or    %ecx,%eax
  1069.      pop    %edx
  1070.      pop    %ecx
  1071. -    pop    %ebp
  1072. +/*    pop    %ebp */
  1073.      ret
  1074.  
  1075.  /**************************************************************************
  1076. @@ -176,8 +182,8 @@
  1077.      .globl    getchar
  1078.  getchar:
  1079.  _getchar:
  1080. -    push    %ebp
  1081. -    mov    %esp,%ebp
  1082. +/*    push    %ebp
  1083. +    mov    %esp,%ebp */
  1084.      push    %ebx
  1085.      call    _prot_to_real
  1086.      movb    $0x0,%ah
  1087. @@ -188,7 +194,7 @@
  1088.      xor    %eax,%eax
  1089.      movb    %bl,%al
  1090.      pop    %ebx
  1091. -    pop    %ebp
  1092. +/*    pop    %ebp */
  1093.      ret
  1094.  
  1095.  /**************************************************************************
  1096. @@ -198,8 +204,8 @@
  1097.      .globl    iskey
  1098.  iskey:
  1099.  _iskey:
  1100. -    push    %ebp
  1101. -    mov    %esp,%ebp
  1102. +/*    push    %ebp
  1103. +    mov    %esp,%ebp */
  1104.      push    %ebx
  1105.      call    _prot_to_real
  1106.      xor    %ebx,%ebx
  1107. @@ -214,10 +220,86 @@
  1108.      xor    %eax,%eax
  1109.      movb    %bl,%al
  1110.      pop    %ebx
  1111. -    pop    %ebp
  1112. +/*    pop    %ebp */
  1113.      ret
  1114.  
  1115.  
  1116. +
  1117. +/**************************************************************************
  1118. +MEMSIZE - Determine size of extended memory
  1119. +**************************************************************************/
  1120. +
  1121. +    .globl    _memsize
  1122. +    .globl    memsize
  1123. +memsize:
  1124. +_memsize:
  1125. +    push    %ebx
  1126. +    call    _prot_to_real
  1127. +    .byte    0xb8
  1128. +    .word    0x8800
  1129. +    int    $0x15
  1130. +    mov    %ax,%bx
  1131. +    opsize
  1132. +    call    _real_to_prot
  1133. +    xor    %eax,%eax
  1134. +    mov    %bx,%ax
  1135. +    pop    %ebx
  1136. +    ret
  1137. +
  1138. +/**************************************************************************
  1139. +START_LINUX - Call linux starter code (real mode)
  1140. +**************************************************************************/
  1141. +    .globl    _start_linux
  1142. +    .globl    start_linux
  1143. +start_linux:
  1144. +_start_linux:
  1145. +    call    _prot_to_real
  1146. +    opsize
  1147. +    call    1f
  1148. +    opsize
  1149. +    call    _real_to_prot
  1150. +    ret
  1151. +1:    opsize
  1152. +    ljmp    $0x9020,$0x0
  1153. +
  1154. +    .globl    _xstart
  1155. +    .globl    xstart
  1156. +
  1157. +xstart:  /* FIXME: this code is rather ugly! could some x86 programmer please*/
  1158. +_xstart: /* come up with something better (I have no clue of x86 programming)*/
  1159. +    pushl    %ebx
  1160. +    pushl    %ecx
  1161. +    movw    12(%esp,1),%eax /* ugly self-modifying code! */
  1162. +    movw    %eax,2f+2
  1163. +    movw    $0x0,2f+4
  1164. +    movw    14(%esp,1),%eax
  1165. +    movw    %eax,2f+6
  1166. +    movl    20(%esp,1),%ecx
  1167. +    movl    16(%esp,1),%ebx
  1168. +    call    _prot_to_real
  1169. +    opsize
  1170. +    ljmp    $(RELOC>>4),$1f-_romstart /* flush cache? */
  1171. +1:    nop
  1172. +    opsize
  1173. +    pushl    %ecx   /* bootp record */
  1174. +    opsize
  1175. +    pushl    %ebx   /* file header */
  1176. +    opsize
  1177. +    call    2f     /* return addr */
  1178. +    opsize
  1179. +    popl    %eax
  1180. +    opsize
  1181. +    popl    %eax
  1182. +    opsize    
  1183. +    call    _real_to_prot
  1184. +    popl    %ecx
  1185. +    popl    %ebx
  1186. +    ret
  1187. +2:    opsize
  1188. +    ljmp    $(RELOC>>4),$3f-_romstart
  1189. +3:    opsize
  1190. +    ret
  1191. +    
  1192.  /*
  1193.   * C library -- _setjmp, _longjmp
  1194.   *
  1195.